package org.common.container;

import java.util.Comparator;


import org.graph.base.Graph;
import org.graph.base.Edge.Direction;
import org.graph.base.GraphFactory;
import org.graph.base.Node;

import org.common.treebuilder.TreeNodeCollection;
import org.common.treebuilder.TreeContainer;
import org.objective.base.CommonObject;

/**
 *
 * @author gus
 */
public class Container<T extends CommonObject> implements TreeContainer<Node<Long, T>, T>
{
    protected final Graph<Long, T, Long> storage;
    protected Comparator<Node<Long, T>> comparator = null;
    protected Node<Long, T> dummyNode;

    public Container() throws Exception
    {
        this.storage = GraphFactory.<Long, T, Long>makeGraphBaseEdgeListFactory().makeGraph(true);
        this.dummyNode = createDummyNode();
    }

    public Container(Comparator<Node<Long, T>> comparator) throws Exception
    {
        this();
        this.comparator = comparator;
    }

    public int size()
    {
        return storage.getNodesCount() - 1;
    }

    @Override
    public void flush() throws Exception
    {
        storage.clear();
        dummyNode = createDummyNode();
    }

    @Override
    public Node<Long, T> createTreeNode(T object, Node<Long, T> parent) throws Exception
    {
        if (parent == null)
        {
            parent = dummyNode;
        }

        Node<Long, T> node = storage.makeNode(object.getOid(), object);
        storage.makeEdge(parent, node, null, Direction.DIRECT);
        return node;
    }

    @Override
    public boolean removeTreeNode(Node<Long, T> node) throws Exception
    {
        if (node == null)
        {
            return false;
        }
        if (storage.findProceedEdges(node, Direction.DIRECT).isEmpty())
        {
            return storage.removeNode(node.getKey());
        }
        return false;
    }

    @Override
    public void removeSubTreeFor(Node<Long, T> node) throws Exception
    {
        throw new Exception("not implement");
    }

    private Node<Long, T> createDummyNode() throws Exception
    {
        return storage.makeNode(-9148776628713234722L, null);
    }

    @Override
    public TreeNodeCollection<Node<Long, T>, T> getSubCollection(Node<Long, T> parent)
    {
        return new TreeNodeCollectionImpl(this, parent);
    }
}
